
#ifndef __boost_asio_network_h__
#define __boost_asio_network_h__

#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/asio.hpp>
#include "packet.h"
#include "Inetwork.h"


template<class T> class MtQueue
{
public:
	MtQueue(unsigned inMax=0) : max(inMax) {}
	void Push(const T& in);
	bool Pop(T& out);
private:
	unsigned max;
	std::list<T> q;
	boost::mutex m;
};


class socketx : public Isocket
{
public:
	socketx(boost::asio::io_service& inio,
		boost::shared_ptr<boost::asio::ip::tcp::socket> ins);
   virtual ~socketx();
public:
	virtual bool is_open() ;
	virtual void start_async();
	virtual bool send(const packet& out) ;
	virtual bool send_async(const packet& out);
	virtual bool recv(packet& in);
	virtual bool recv_async(packet& in);
    virtual void set_close_handle(sokcet_close_handle close_handle) ;
	virtual void close();
private:
	sokcet_close_handle close_handle_;
private:
	boost::asio::io_service& io;
	boost::shared_ptr<boost::asio::ip::tcp::socket> s;
	bool open;
	bool async_ready;
	MtQueue<packet> recv_datas;
	packet::size_type recvSize;
	packet::data_type recvBuffer[packet::MAX_SIZE];
	packet::data_type sendBuffer[packet::MAX_SIZE + sizeof(packet::size_type)];
private:
	// asio callbacks
	void HandleWrite(const boost::system::error_code& e);
	void HandleReadHeader(const boost::system::error_code& e);
	void HandleReadBody(const boost::system::error_code& e);
	void HandleClose();
};

class network :public Inetwork
{
public:
	network();
	virtual ~network();
	virtual bool connect(const char* addr, const char* port,connect_callback onconnect);
	virtual bool accept(unsigned short port,accept_callback newclient,unsigned max=0);
	virtual void stop() ;
protected:
private:
    //virtual int get_accept_num() ;
	bool handle_accept(boost::shared_ptr<boost::asio::ip::tcp::socket> socket_ptr,const boost::system::error_code& error);
	boost::asio::io_service io;
	std::list<boost::shared_ptr<Isocket> > sockets;
	boost::shared_ptr<boost::thread> t;
	boost::shared_ptr<boost::asio::ip::tcp::acceptor> acceptor_;
private:
	unsigned max_;
	accept_callback newclient_call_;
	bool session_start(accept_callback newclient_call,unsigned max,
		bool baccept,bool done,boost::shared_ptr<boost::asio::ip::tcp::socket> s);
};




template<class T> void MtQueue<T>::Push(const T& in)
{
	boost::mutex::scoped_lock l(m);
	q.push_back(in);
	if(max && q.size() > max)
	{
		q.pop_front();
	}
}

template<class T> bool MtQueue<T>::Pop(T& out)
{
	boost::mutex::scoped_lock l(m);
	if(q.empty()) return false;
	out = q.front();
	q.pop_front();
	return true;
}







#endif //__boost_asio_network_h__
